use std::collections::BTreeMap;

use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Configs {
    pub tenant: String,
    pub data_id: String,
    pub group: String,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ListeningConfigs {
    #[serde(rename = "Listening-Configs")]
    pub listening_configs: String,
}
impl ListeningConfigs {
    pub fn new(config: &Configs, config_md5: &str) -> Self {
        let listening_configs = format!(
            "dataId{}^2Group{}^2contentMD5{}^2tenant{}^1",
            &config.data_id, &config.group, config_md5, &config.tenant
        );
        Self {
            listening_configs: listening_configs,
        }
    }
}

impl Default for ListeningConfigs {
    fn default() -> Self {
        Self {
            listening_configs: Default::default(),
        }
    }
}
#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct HistoryConfigs {
    #[serde(alias = "pageNo")]
    pub page_no: String,
    #[serde(alias = "pageSize")]
    pub page_size: String,
    #[serde(flatten)]
    pub configs: Configs,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct HistoryConfigInfo {
    pub nid: Option<String>,
    #[serde(flatten)]
    pub configs: Configs,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct PreviousHistoryConfigInfo {
    pub id: Option<String>,
    #[serde(flatten)]
    pub configs: Configs,
}
impl Default for PreviousHistoryConfigInfo {
    fn default() -> Self {
        Self {
            id: Some("5".to_string()),
            configs: Default::default(),
        }
    }
}

impl PreviousHistoryConfigInfo {
    pub fn new(id: Option<String>, configs: Configs) -> Self {
        Self { id, configs }
    }
}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct HistoryConfigsRes {
    #[serde(alias = "totalCount")]
    pub total_count: i32,
    #[serde(alias = "pageNumber")]
    pub page_number: i32,
    #[serde(alias = "pagesAvailable")]
    pub pages_available: i32,
    #[serde(alias = "pageItems")]
    pub page_items: Vec<HistoryConfigInfoRes>,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct HistoryConfigInfoRes {
    pub id: Option<String>,
    #[serde(alias = "lastId")]
    pub last_id: Option<i32>,
    #[serde(flatten)]
    pub configs: Configs,
    pub md5: Option<String>,
    pub content: Option<String>,
    #[serde(alias = "srcIp")]
    pub src_ip: Option<String>,
    #[serde(alias = "srcUser")]
    pub src_user: Option<String>,
    #[serde(alias = "opType")]
    pub op_type: Option<String>,
    #[serde(alias = "createdTime")]
    pub created_time: Option<String>,
    #[serde(alias = "lastModifiedTime")]
    pub last_modified_time: Option<String>,
}

impl HistoryConfigInfo {
    pub fn new(nid: String, configs: Configs) -> Self {
        Self {
            configs,
            nid: Some(nid),
        }
    }
}

impl Default for HistoryConfigs {
    fn default() -> Self {
        Self {
            page_no: "1".to_string(),
            page_size: "100".to_string(),
            configs: Default::default(),
        }
    }
}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ConfigsPublish {
    pub content: String, //string	是	配置内容
    #[serde(rename = "type")]
    pub content_type: String, //	否	配置类型
    #[serde(flatten)]
    pub configs: Configs,
}

#[derive(Debug, Deserialize, Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct ConfigsRes<T> {
    pub header_map: T,
    pub content: String,
}

impl Default for Configs {
    fn default() -> Self {
        Self {
            tenant: "".to_string(),
            data_id: "test".to_string(),
            group: "DEFAULT_GROUP".to_string(),
        }
    }
}
impl Default for ConfigsPublish {
    fn default() -> Self {
        let mut map = BTreeMap::new();
        map.insert("x".to_string(), 1.0);
        map.insert("y".to_string(), 2.0);

        // Serialize it to a YAML string.
        let yaml = serde_yaml::to_string(&map).unwrap();
        Self {
            configs: Configs::default(),
            content: yaml,
            content_type: "yaml".to_string(),
        }
    }
}
impl Configs {}
